package com.example.samplemanagement.service;

import com.example.samplemanagement.dto.SampleTrackingHistoryDto;
import com.example.samplemanagement.dto.SampleTrackingOverviewDto;
import com.example.samplemanagement.dto.SampleTrackingRequestDto;
import com.example.samplemanagement.model.Customer;
import com.example.samplemanagement.model.Sample;
import com.example.samplemanagement.model.SampleTracking;
import com.example.samplemanagement.repository.CustomerRepository;
import com.example.samplemanagement.repository.SampleRepository;
import com.example.samplemanagement.repository.SampleTrackingRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SampleTrackingService {

    @Autowired
    private SampleTrackingRepository sampleTrackingRepository;
    @Autowired
    private SampleRepository sampleRepository;
    @Autowired
    private CustomerRepository customerRepository;

    /**
     * 添加新的样品跟踪记录
     * 现在接收 SampleTrackingRequestDto，从中提取ID并查找完整实体
     */
    @Transactional // 确保整个操作在一个事务中完成
    public SampleTracking addSampleTracking(SampleTrackingRequestDto requestDto) { // 接收新的DTO
        // 1. 根据前端提供的ID，从数据库中查找完整的 Sample 和 Customer 实体
        Sample sample = sampleRepository.findById(requestDto.getSampleId())
                .orElseThrow(() -> new NoSuchElementException("Sample not found with ID: " + requestDto.getSampleId()));
        Customer customer = customerRepository.findById(requestDto.getCustomerId())
                .orElseThrow(() -> new NoSuchElementException("Customer not found with ID: " + requestDto.getCustomerId()));

        // 2. 构建 SampleTracking 对象
        SampleTracking sampleTracking = new SampleTracking();
        sampleTracking.setSample(sample);
        sampleTracking.setCustomer(customer);
        sampleTracking.setCommunicationType(requestDto.getCommunicationType());
        sampleTracking.setFeedbackContent(requestDto.getFeedbackContent());
        sampleTracking.setNotes(requestDto.getNotes());

        // 将字符串类型的 feedbackType 转换为枚举类型
        if (requestDto.getFeedbackType() != null && !requestDto.getFeedbackType().isEmpty()) {
            try {
                sampleTracking.setFeedbackType(SampleTracking.FeedbackType.valueOf(requestDto.getFeedbackType().toUpperCase()));
            } catch (IllegalArgumentException e) {
                // 处理无效的反馈类型，例如设置为 NONE 或抛出异常
                System.err.println("Invalid feedback type received: " + requestDto.getFeedbackType() + ". Setting to NONE.");
                sampleTracking.setFeedbackType(SampleTracking.FeedbackType.NONE);
            }
        } else {
            sampleTracking.setFeedbackType(SampleTracking.FeedbackType.NONE); // 默认无反馈
        }

        // trackingDate 和 isOrderPlaced 将由 @PrePersist 自动设置
        // 或者您也可以在这里手动设置：
        // sampleTracking.setTrackingDate(LocalDate.now());
        // sampleTracking.setOrderPlaced(false);

        // 3. 保存到数据库
        return sampleTrackingRepository.save(sampleTracking);
    }

    /**
     * 获取所有样品跟踪记录。
     * 此方法直接返回数据库中的所有 SampleTracking 记录，
     * 主要用于前端计算总数和生成图表（如反馈分布和沟通类型分布）。
     */
    public List<SampleTracking> getAllSampleTrackingRecords() {
        // Fetch all SampleTracking entities, but ensure Sample and Customer lazy-loaded
        // fields are not eagerly fetched for this specific use case to avoid large payload
        // if not needed, or use a specific DTO if full object is not necessary.
        // For simplicity, we are returning entities directly, but if this causes N+1
        // issues or large payloads, consider a dedicated DTO for charts.
        return sampleTrackingRepository.findAll();
    }


    /**
     * 获取样品跟踪概览列表 (聚合数据)
     * 这是最复杂的业务逻辑部分，需要查询并汇总每个样品-客户组合的数据
     */
    public List<SampleTrackingOverviewDto> getSampleTrackingOverview(String sampleNumber, String companyName, String status) {
        List<SampleTracking> allTrackings = sampleTrackingRepository.findAll();

        // 根据筛选条件过滤数据
        List<SampleTracking> filteredTrackings = allTrackings.stream()
                .filter(tracking -> {
                    // 确保 sample 和 customer 不为 null，因为 @JsonIgnore 只影响序列化，不影响实际对象是否加载
                    boolean matchesSample = sampleNumber == null || sampleNumber.isEmpty() ||
                            (tracking.getSample() != null && tracking.getSample().getSampleNumber() != null && tracking.getSample().getSampleNumber().contains(sampleNumber));
                    boolean matchesCustomer = companyName == null || companyName.isEmpty() ||
                            (tracking.getCustomer() != null && tracking.getCustomer().getCompanyName() != null && tracking.getCustomer().getCompanyName().contains(companyName));
                    boolean matchesStatus = status == null || status.isEmpty() ||
                            (status.equals("已转化") && tracking.isOrderPlaced()) ||
                            (status.equals("待转化") && !tracking.isOrderPlaced());
                    return matchesSample && matchesCustomer && matchesStatus;
                })
                .collect(Collectors.toList());

        // 按样品和客户分组，聚合数据
        Map<String, List<SampleTracking>> groupedTrackings = filteredTrackings.stream()
                .collect(Collectors.groupingBy(tracking ->
                        // 确保 getSample() 和 getCustomer() 不为 null
                        (tracking.getSample() != null ? tracking.getSample().getId() : "null_sample") + "_" +
                                (tracking.getCustomer() != null ? tracking.getCustomer().getId() : "null_customer") // 使用组合ID作为key
                ));

        List<SampleTrackingOverviewDto> overviewList = new ArrayList<>();

        for (Map.Entry<String, List<SampleTracking>> entry : groupedTrackings.entrySet()) {
            List<SampleTracking> trackingsForGroup = entry.getValue();

            // 找到最新的一条记录
            SampleTracking latestTracking = trackingsForGroup.stream()
                    .max(Comparator.comparing(SampleTracking::getTrackingDate)
                            .thenComparing(SampleTracking::getId)) // 如果日期相同，ID更大的更新
                    .orElse(null);

            if (latestTracking == null) {
                continue; // 应该不会发生，但以防万一
            }

            // 计算沟通频次
            Long communicationCount = (long) trackingsForGroup.size();

            // 计算反馈率 (至少有一个“积极”、“中性”、“消极”反馈才算有反馈)
            long feedbackCount = trackingsForGroup.stream()
                    .filter(t -> t.getFeedbackType() != SampleTracking.FeedbackType.NONE)
                    .count();
            double feedbackRate = communicationCount > 0 ? (double) feedbackCount / communicationCount : 0.0;

            // 获取最新反馈内容和类型
            SampleTracking.FeedbackType latestFeedbackType = latestTracking.getFeedbackType();
            String latestFeedbackContent = latestTracking.getFeedbackContent();

            // 获取最新沟通日期
            LocalDate latestCommunicationDate = latestTracking.getTrackingDate();

            // 获取下单状态（取最新的记录的下单状态）
            boolean isOrderPlaced = latestTracking.isOrderPlaced();

            // 为每个样品-客户组合生成一个伪唯一ID，用于前端的key属性
            // 确保 sample 和 customer 不为 null
            Long overviewId = null;
            if (latestTracking.getSample() != null && latestTracking.getCustomer() != null) {
                overviewId = Long.parseLong(latestTracking.getSample().getId().toString() + latestTracking.getCustomer().getId().toString());
            }


            overviewList.add(new SampleTrackingOverviewDto(
                    overviewId,
                    latestTracking.getSample(), // 注意：这里返回的是完整的Sample/Customer对象，前端需要处理
                    latestTracking.getCustomer(), // 如果前端只显示名称，这没问题
                    communicationCount,
                    feedbackRate,
                    latestFeedbackType,
                    latestFeedbackContent,
                    latestCommunicationDate,
                    isOrderPlaced
            ));
        }

        // 可以根据需要对 overviewList 进行排序，例如按最新沟通日期倒序
        overviewList.sort(Comparator.comparing(SampleTrackingOverviewDto::getLatestCommunicationDate, Comparator.nullsLast(Comparator.reverseOrder())));

        return overviewList;
    }

    /**
     * 获取特定样品和客户的所有跟踪历史记录
     */
    public SampleTrackingHistoryDto getSampleTrackingHistory(Long sampleId, Long customerId) {
        Sample sample = sampleRepository.findById(sampleId)
                .orElseThrow(() -> new NoSuchElementException("Sample not found with ID: " + sampleId));
        Customer customer = customerRepository.findById(customerId)
                .orElseThrow(() -> new NoSuchElementException("Customer not found with ID: " + customerId));

        List<SampleTracking> history = sampleTrackingRepository.findBySampleIdAndCustomerIdOrderByTrackingDateDesc(sampleId, customerId);

        SampleTrackingHistoryDto dto = new SampleTrackingHistoryDto();
        dto.setSampleName(sample.getSampleName());
        dto.setSampleNumber(sample.getSampleNumber());
        dto.setCompanyName(customer.getCompanyName());
        dto.setHistory(history);
        return dto;
    }

    /**
     * 标记特定样品-客户组合为已下单
     */
    @Transactional
    public void markAsOrdered(Long sampleId, Long customerId) {
        // 查找所有与此样品-客户组合相关的跟踪记录，并将它们都标记为已下单
        // 注意：这里查找所有是为了确保所有相关记录都被更新，如果只需要更新最新一条，则逻辑不同
        List<SampleTracking> records = sampleTrackingRepository.findBySampleIdAndCustomerIdOrderByTrackingDateDesc(sampleId, customerId);
        if (records.isEmpty()) {
            throw new NoSuchElementException("No tracking records found for Sample ID: " + sampleId + " and Customer ID: " + customerId);
        }
        for (SampleTracking record : records) {
            record.setOrderPlaced(true);
            sampleTrackingRepository.save(record);
        }
    }
    @Transactional
    public void deleteBySampleAndCustomer(Long sampleId, Long customerId) {
        // 验证样品和客户是否存在
        if (!sampleRepository.existsById(sampleId)) {
            throw new NoSuchElementException("样品不存在，ID: " + sampleId);
        }
        if (!customerRepository.existsById(customerId)) {
            throw new NoSuchElementException("客户不存在，ID: " + customerId);
        }

        // 删除所有相关跟踪记录
        List<SampleTracking> records = sampleTrackingRepository.findBySampleIdAndCustomerId(sampleId, customerId);
        if (records.isEmpty()) {
            throw new NoSuchElementException("未找到样品ID: " + sampleId + " 和客户ID: " + customerId + " 的跟踪记录");
        }

        sampleTrackingRepository.deleteAll(records);
    }
    // 更新单条跟踪记录
    @Transactional
    public SampleTracking updateTracking(Long trackingId, SampleTrackingRequestDto requestDto) {
        SampleTracking tracking = sampleTrackingRepository.findById(trackingId)
                .orElseThrow(() -> new NoSuchElementException("跟踪记录不存在"));

        // 更新字段
        if (requestDto.getCommunicationType() != null) {
            tracking.setCommunicationType(requestDto.getCommunicationType());
        }
        if (requestDto.getFeedbackType() != null) {
            tracking.setFeedbackType(SampleTracking.FeedbackType.valueOf(requestDto.getFeedbackType()));
        }
        tracking.setFeedbackContent(requestDto.getFeedbackContent());
        tracking.setNotes(requestDto.getNotes());

        return sampleTrackingRepository.save(tracking);
    }

    // 删除单条跟踪记录
    @Transactional
    public void deleteTracking(Long trackingId) {
        if (!sampleTrackingRepository.existsById(trackingId)) {
            throw new NoSuchElementException("跟踪记录不存在");
        }
        sampleTrackingRepository.deleteById(trackingId);
    }
    // --- CRUD for Sample and Customer (保持不变) ---
    public List<Sample> getAllSamples() {
        return sampleRepository.findAll();
    }

    public Sample saveSample(Sample sample) {
        if (sample.getCreationDate() == null) {
            sample.setCreationDate(LocalDate.now());
        }
        return sampleRepository.save(sample);
    }

    public Sample updateSample(Long id, Sample sampleDetails) {
        Sample sample = sampleRepository.findById(id)
                .orElseThrow(() -> new NoSuchElementException("Sample not found with id " + id));
        sample.setSampleNumber(sampleDetails.getSampleNumber());
        sample.setSampleName(sampleDetails.getSampleName());
        sample.setCategory(sampleDetails.getCategory());
        sample.setDesigner(sampleDetails.getDesigner());
        sample.setSampleType(sampleDetails.getSampleType()); // 确保更新新字段
        sample.setSampleSource(sampleDetails.getSampleSource()); // 确保更新新字段
        sample.setStatus(sampleDetails.getStatus());
        sample.setStorageLocation(sampleDetails.getStorageLocation()); // 确保更新新字段
        sample.setUsageStatus(sampleDetails.getUsageStatus()); // 确保更新新字段
        sample.setNotes(sampleDetails.getNotes()); // 确保更新新字段
        return sampleRepository.save(sample);
    }

    public void deleteSample(Long id) {
        if (!sampleRepository.existsById(id)) {
            throw new NoSuchElementException("Sample not found with id " + id);
        }
        sampleRepository.deleteById(id);
    }

    public List<Customer> getAllCustomers() {
        return customerRepository.findAll();
    }

    public Customer saveCustomer(Customer customer) {
        return customerRepository.save(customer);
    }

    public Customer updateCustomer(Long id, Customer customerDetails) {
        Customer customer = customerRepository.findById(id)
                .orElseThrow(() -> new NoSuchElementException("Customer not found with id " + id));
        customer.setCompanyName(customerDetails.getCompanyName());
        customer.setContactPerson(customerDetails.getContactPerson());
        customer.setContactPhone(customerDetails.getContactPhone());
        customer.setCustomerLevel(customerDetails.getCustomerLevel());
        customer.setResponsibleSales(customerDetails.getResponsibleSales());
        return customerRepository.save(customer);
    }

    public void deleteCustomer(Long id) {
        if (!customerRepository.existsById(id)) {
            throw new NoSuchElementException("Customer not found with id " + id);
        }
        customerRepository.deleteById(id);
    }
}
